package org.eclipse.wst.server.preview.openejb.jetty.builder;

import org.apache.openejb.assembler.classic.EnterpriseBeanInfo;
import org.apache.openejb.assembler.classic.Assembler;
import org.apache.openejb.assembler.classic.AppInfo;
import org.apache.openejb.assembler.classic.EjbJarInfo;
import org.apache.openejb.loader.SystemInstance;

import java.util.Collection;
import java.util.List;

/**This class is responsible to find the EnterpriseBeanInfo from a ejb bean
 * deployed on the OpenEJB server. This class was copied from the Jonathan Gallimore's work
 * "Functional testing with OpenEJB, Jetty and Selenium" (http://openejb.apache.org/functional-testing-with-openejb-jetty-and-selenium.html)
 * 
 * 
 * @author Marcelo de Oliveira Dias
 *
 */

public class EJBHelper {
	
	/**Search for EnterpriseBeanInfo deployed on the OpenEJB container.
	 * 
	 * @param ejbLink - The string link of the bean searched. 
	 * @return the EnterpriseBeanInfo found.
	 */
    public EnterpriseBeanInfo getEJBInfo(String ejbLink) {
        Collection<AppInfo> deployedApplications = getDeployedApps();
        for (AppInfo app : deployedApplications) {
            List<EjbJarInfo> ejbJars = app.ejbJars;
            for (EjbJarInfo ejbJar : ejbJars) {
                List<EnterpriseBeanInfo> enterpriseBeans = ejbJar.enterpriseBeans;
                for (EnterpriseBeanInfo enterpriseBean : enterpriseBeans) {
                    if (enterpriseBean.ejbDeploymentId.equals(ejbLink)) {
                        return enterpriseBean;
                    }
                }
            }
        }

        return null;
    }

    /**Search for EnterpriseBeanInfo deployed on the OpenEJB container.
	 * 
	 * @param fieldType - The class of the bean searched. 
	 * @return the EnterpriseBeanInfo found.
	 */
    public EnterpriseBeanInfo getBeanInfo(Class<?> fieldType) {
        Collection<AppInfo> deployedApplications = getDeployedApps();
        
        for (AppInfo deployedApplication : deployedApplications) {
            List<EjbJarInfo> ejbJars = deployedApplication.ejbJars;
            
            for (EjbJarInfo ejbJar : ejbJars) {
                List<EnterpriseBeanInfo> enterpriseBeans = ejbJar.enterpriseBeans;
                
                for (EnterpriseBeanInfo enterpriseBean : enterpriseBeans) {
                    List<String> localInterfaces = enterpriseBean.businessLocal;
                    if (localInterfaces.contains(fieldType.getCanonicalName())) {
                        return enterpriseBean;
                    }
                    List<String> remoteInterfaces = enterpriseBean.businessRemote;
                    if (remoteInterfaces.contains(fieldType.getCanonicalName())) {
                        return enterpriseBean;
                    }
                }
            }
        }

        return null;
    }

    /**Get the component Assembler of the OpenEJB container that's running
     * and returns a collection of the EJB's deployed.
     * 
     * @return a collection of the EJB's deployed.
     */
    private Collection<AppInfo> getDeployedApps() {
        Assembler assembler = SystemInstance.get().getComponent(Assembler.class);
        return assembler.getDeployedApplications();
    }
}
